import type { App, Directive, DirectiveBinding } from "vue";

/**
 * 水波纹指令
 * 用法：
 * <!-- 基础用法 -->
 * <el-button v-ripple>点击查看水波纹效果</el-button>
 *
 * <!-- 自定义颜色 -->
 * <el-button v-ripple="{ color: 'rgba(0, 0, 0, 0.2)' }">
 *   自定义水波纹颜色
 * </el-button>
 */
export interface RippleOptions {
  color?: string;
}

export const vRipple: Directive = {
  mounted(el: HTMLElement, binding: DirectiveBinding) {
    // 获取指令的配置参数
    const options: RippleOptions = binding.value || {};

    // 设置元素为相对定位，并隐藏溢出部分
    el.style.position = "relative";
    el.style.overflow = "hidden";

    // 点击事件处理
    el.addEventListener("mousedown", (e: MouseEvent) => {
      const rect = el.getBoundingClientRect();
      const left = e.clientX - rect.left;
      const top = e.clientY - rect.top;

      // 创建水波纹元素
      const ripple = document.createElement("div");
      const diameter = Math.max(el.clientWidth, el.clientHeight);
      const radius = diameter / 2;

      // 根据直径计算动画时间（直径越大，动画时间越长）
      const baseTime = 600; // 基础动画时间（毫秒）
      const scaleFactor = 0.5; // 缩放因子
      const animationDuration = baseTime + diameter * scaleFactor;

      // 设置水波纹的尺寸和位置
      ripple.style.width = ripple.style.height = `${diameter}px`;
      ripple.style.left = `${left - radius}px`;
      ripple.style.top = `${top - radius}px`;
      ripple.style.position = "absolute";
      ripple.style.borderRadius = "50%";
      ripple.style.pointerEvents = "none";

      // 判断是否为有色按钮（Element Plus 按钮类型）
      const buttonTypes = [
        "primary",
        "info",
        "warning",
        "danger",
        "success",
      ].map((type) => `el-button--${type}`);
      const isColoredButton = buttonTypes.some((type) =>
        el.classList.contains(type),
      );
      const defaultColor = isColoredButton
        ? "rgba(255, 255, 255, 0.35)" // 有色按钮使用白色水波纹
        : "var(--el-color-primary-light-7)"; // 默认按钮使用主题色水波纹

      // 设置水波纹颜色、初始状态和过渡效果
      ripple.style.backgroundColor = options.color || defaultColor;
      ripple.style.transform = "scale(0)";
      ripple.style.transition = `transform ${animationDuration}ms cubic-bezier(0.3, 0, 0.2, 1), opacity ${animationDuration}ms cubic-bezier(0.3, 0, 0.5, 1)`;
      ripple.style.zIndex = "1";

      // 添加水波纹元素到DOM中
      el.appendChild(ripple);

      // 触发动画
      requestAnimationFrame(() => {
        ripple.style.transform = "scale(2)";
        ripple.style.opacity = "0";
      });

      // 动画结束后移除水波纹元素
      setTimeout(() => {
        ripple.remove();
      }, animationDuration + 500); // 增加500ms缓冲时间
    });
  },
};

export function setupRippleDirective(app: App) {
  app.directive("ripple", vRipple);
}
